import { injectable, inject } from '@flowgram.ai/free-layout-editor';
import {
  FreeLayoutPluginContext,
  SelectionService,
  Playground,
  WorkflowDocument,
} from '@flowgram.ai/free-layout-editor';

import { McpInfo } from '@/typings/mcp';
import { ChatModelType } from '@/typings/chatmodel';

import { DEFAULT_SERVER_CONFIG } from '../plugins/runtime-plugin/server-client/constant';

/**
 * Docs: https://inversify.io/docs/introduction/getting-started/
 * Warning: Use decorator legacy
 *   // rsbuild.config.ts
 *   {
 *     source: {
 *       decorators: {
 *         version: 'legacy'
 *       }
 *     }
 *   }
 * Usage:
 *  1.
 *    const myService = useService(CustomService)
 *    myService.save()
 *  2.
 *    const myService = useClientContext().get(CustomService)
 *  3.
 *    const myService = node.getService(CustomService)
 */
@injectable()
export class CustomService {
  @inject(FreeLayoutPluginContext) ctx: FreeLayoutPluginContext;

  @inject(SelectionService) selectionService: SelectionService;

  @inject(Playground) playground: Playground;

  @inject(WorkflowDocument) document: WorkflowDocument;

  save() {
    console.log(this.document.toJSON());
  }

  async sendToServer(data?: unknown): Promise<any> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/flow/run`;
    try {
      if (!data) {
        throw new Error('data is required');
      }
      const response = await fetch(url, {
        method: 'POST',
        body: JSON.stringify(data),
        headers: {
          'Content-Type': 'application/json',
        },
      });
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      console.log('>>>>> result: ', result);
      return result;
    } catch (error) {
      console.log('>>>>> error: ', error);
      throw error;
    }
  }

  // 添加获取模型列表的新方法
  async getModelList(signal?: AbortSignal): Promise<Array<ChatModelType>> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/model/list`;
    try {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
        signal, // Add signal parameter
      });
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      console.log('model result', result);
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      return result.data || [];
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return [];
    }
  }

  // 添加获取大语言模型列表的新方法
  async getChatModelList(info: ChatModelType, signal?: AbortSignal): Promise<Array<string>> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/model/chatmodel/list`;
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(info),
        signal, // Add signal parameter
      });
      // console.log('chatmodel response:', response);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      console.log('chatmodel result', result);
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      return result.data || [];
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return [];
    }
  }

  // 添加获取大语言模型列表的新方法
  async saveModel(info: ChatModelType, signal?: AbortSignal): Promise<Array<string>> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/model/save`;
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(info),
        signal, // Add signal parameter
      });
      // console.log('chatmodel response:', response);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      console.log('chatmodel result', result);
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      return result.data || [];
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return [];
    }
  }

  // 添加获取大语言模型列表的新方法
  async deleteModel(id: number, signal?: AbortSignal): Promise<Array<string>> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/model/delete`;
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ id: id }),
        signal, // Add signal parameter
      });
      // console.log('chatmodel response:', response);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      console.log('chatmodel result', result);
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      return result.data || [];
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return [];
    }
  }

  // 添加获取MCP列表的新方法
  async getMcpList(signal?: AbortSignal): Promise<Array<McpInfo>> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/mcp/list`;
    try {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
        signal, // Add signal parameter
      });
      console.log('response:', response);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      console.log('result', result);
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      return result.data || [];
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return [];
    }
  }

  // 添加获取模型列表的新方法
  async saveMcp(data: any, signal?: AbortSignal): Promise<McpInfo> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/mcp/save`;
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
        signal, // Add signal parameter
      });
      console.log('response:', response);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      console.log('resault', result);
      return result.data || {};
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return {
        ID: 0,
        Name: '',
        McpType: '',
        Url: '',
        Prompts: '',
        Ressource: '',
        Tools: '',
      };
    }
  }

  // 添加获取模型列表的新方法
  async deleteMcp(id: number, signal?: AbortSignal): Promise<{ success: boolean }> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/mcp/delete`;
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ id: id }),
        signal, // Add signal parameter
      });
      console.log('response:', response);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      console.log('resault', result);
      return result.data || {};
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return {
        success: false,
      };
    }
  }

  // 添加获取模型列表的新方法
  async getFlowList(signal?: AbortSignal): Promise<Array<{ ID: string; Name: string }>> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/flow/list`;
    try {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
        signal, // Add signal parameter
      });
      console.log('response:', response);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      return result.data || [];
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return [];
    }
  }

  // 添加获取模型列表的新方法
  async deleteFlow(id: string, signal?: AbortSignal): Promise<{ success: boolean }> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/flow/delete`;
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ id: id }),
        signal, // Add signal parameter
      });
      console.log('response:', response);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      console.log('resault', result);
      return result.data || [];
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return { success: false };
    }
  }

  // 添加获取模型列表的新方法
  async saveFlow(data: string, signal?: AbortSignal): Promise<{ id: number }> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/flow/save`;
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: data,
        signal, // Add signal parameter
      });
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      console.log('resault', result);
      return result.data || [];
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return { id: 0 };
    }
  }

  // 添加获取模型列表的新方法
  async getFlow(
    data: string,
    signal?: AbortSignal
  ): Promise<{ ID: number; Name: string; Script: string }> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/flow/get`;
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: data,
        signal, // Add signal parameter
      });
      console.log('response:', response);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      console.log('resault', result);
      return result.data || [];
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return { ID: 0, Name: '', Script: '' };
    }
  }

  // 添加获取模型列表的新方法
  async runFlow(id: number, signal?: AbortSignal): Promise<{ ID: number }> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/flow/run`;
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ id }),
        signal, // Add signal parameter
      });
      console.log('response:', response);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      console.log('resault', result);
      return result.data || [];
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return { ID: 0 };
    }
  }

  async getFlowMessage(
    id: number,
    sessionId: number,
    message: string,
    signal?: AbortSignal
  ): Promise<ReadableStream<Uint8Array>> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/flow/message`;

    // 创建请求超时控制器
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 100000); // 100秒超时

    // 如果外部有传入 signal，监听它的取消事件
    if (signal) {
      signal.addEventListener('abort', () => {
        controller.abort();
        clearTimeout(timeoutId);
      });
    }

    try {
      // 发送 SSE 请求
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          Accept: 'text/event-stream',
          'Cache-Control': 'no-cache',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ id, sessionId, message }),
        signal: controller.signal,
      });

      clearTimeout(timeoutId);

      // 检查响应状态
      if (!response.ok) {
        throw new Error(`请求失败: ${response.status} ${response.statusText}`);
      }

      // 检查响应类型
      const contentType = response.headers.get('content-type');
      if (!contentType || !contentType.includes('text/event-stream')) {
        throw new Error('无效的响应类型，预期 text/event-stream');
      }

      // 返回可读流
      if (!response.body) {
        throw new Error('响应体为空');
      }

      return response.body;
    } catch (error) {
      clearTimeout(timeoutId);
      throw error;
    }
  }

  // 添加获取模型列表的新方法
  async getSessionList(
    id: number,
    signal?: AbortSignal
  ): Promise<Array<{ SessionId: string; Name: string }>> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/session/list`;
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ flowId: id }),
        signal, // Add signal parameter
      });
      console.log('response:', response);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      return result.data || [];
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return [];
    }
  }

  // 添加获取模型列表的新方法
  async getSession(
    id: string,
    signal?: AbortSignal
  ): Promise<Array<{ Content: string; Role: string }>> {
    const { protocol, domain, port } = DEFAULT_SERVER_CONFIG;
    const baseUrl = port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
    const url = `${baseUrl}/api/session/messages`;
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ sessionId: id }),
        signal, // Add signal parameter
      });
      console.log('response:', response);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      // 假设API返回格式: { data: [{ id: 'model-id', name: 'Model Name' }, ...] }
      return result.data || [];
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        console.log('Error fetching model list:', error);
      }
      return [];
    }
  }
}
